package com.weasel.weixin.commons.accounts;

import com.google.common.collect.ImmutableMap;
import com.weasel.http.HttpClientSecretary;
import com.weasel.http.helper.HttpUrlHelper;
import com.weasel.weixin.commons.CommonRequest;
import com.weasel.weixin.commons.config.CommonConfig;
import com.weasel.weixin.commons.config.CommonConsts;

import java.io.IOException;

/**授权认证
 * Created by Dylan on 2015/10/12.
 */
public class Oauth2AccessTokenRequest  extends CommonRequest {

    private final static String WEIXIN_ACCESSTOKEN_URL = "https://open.weixin.qq.com/connect/oauth2/authorize";

    public final static String SNSAPI_BASE_SCOPE = "snsapi_base"; //静默授权并自动跳转到回调页的。用户感知的就是直接进入了回调页（往往是业务页面）
    public final static String SNSAPI_USERINFO_SCOPE = "snsapi_userinfo"; //这种授权需要用户手动同意，并且由于用户同意过，所以无须关注，就可在授权后获取该用户的基本信息。对于已关注公众号的用户，如果用户从公众号的会话或者自定义菜单进入本公众号的网页授权页，即使是scope为snsapi_userinfo，也是静默授权，用户无感知。

    public Oauth2AccessTokenRequest(CommonConfig config) {
        super(config);
    }

    /**
     * 获取用户授权后的access_token
     * @param code  用户授权后微信服务器传回来的code
     * @return
     * @throws IOException
     */
    public Oauth2AccessTokenResponse getOauth2AccessToken(String code) throws IOException {

        Oauth2AccessTokenResponse response = HttpClientSecretary.get()
                                                                .withURI(CommonConsts.OAUTH2_ACCESS_TOKEN_URL)
                                                                .withParams(ImmutableMap.of("appid",config.getAppid(),"secret",config.getSecret(),"code",code,"grant_type","authorization_code"))
                                                                .doItWithJson(Oauth2AccessTokenResponse.class);

        return response;
    }


    /**
     * 刷新用户授权后的access_token
     * @param refresh_token  第一次调用getOauth2AccessToken获取access_token返回值中的refresh_token字段值
     * @return
     */
    public Oauth2AccessTokenResponse refreshOauth2AccessToken(String refresh_token) throws IOException {

        Oauth2AccessTokenResponse response = HttpClientSecretary.get()
                                                                .withURI(CommonConsts.REFRESH_OAUTH2_ACCESS_TOKEN_URL)
                                                                .withParams(ImmutableMap.of("appid", config.getAppid(), "grant_type", "refresh_token", "refresh_token", refresh_token))
                                                                .doItWithJson(Oauth2AccessTokenResponse.class);
        return response;
    }

    /**
     * 获取微信授权的url
     * @param scope  授权scope，使用Oauth2AccessTokenRequest.SNSAPI_BASE_SCOPE或者使用Oauth2AccessTokenRequest.SNSAPI_USERINFO_SCOPE
     * @param state  状态。设置该状态，用户授权后微信服务器重定向回第三方服务器会带有该参数。
     * @return
     */
    public String getOauth2AccessTokenURL(String scope,String state){

       String url =  HttpUrlHelper.withURL(WEIXIN_ACCESSTOKEN_URL)
                                  .addParam("appid", config.getAppid())
                                  .addParam("redirect_uri", config.getOauth2redirectUri())
                                  .addParam("response_type", "code")
                                  .addParam("scope", scope)
                                  .addParam("state", state)
                                  .build();
        url += "#wechat_redirect";
        return url;
    }

    /**
     * 获取微信授权的url
     * @param scope  授权scope，使用Oauth2AccessTokenRequest.SNSAPI_BASE_SCOPE或者使用Oauth2AccessTokenRequest.SNSAPI_USERINFO_SCOPE
     * @return
     */
    public String getOauth2AccessTokenURL(String scope){

        return getOauth2AccessTokenURL(scope,"STATE");
    }

    /**
     * 验证用户授权的accessToken是否有效
     * @param accessToken 网页授权接口调用凭证
     * @param openId  用户的唯一标识
     * @return
     */
    public boolean accessTokenEnabled(String accessToken,String openId) throws IOException {

        Oauth2AccessTokenResponse response = HttpClientSecretary.get()
                                                                .withURI(CommonConsts.OAUTH2_ACCESS_TOKEN_ENABLED_URL)
                                                                .withParams(ImmutableMap.of("access_token",accessToken,"openid",openId))
                                                                .doItWithJson(Oauth2AccessTokenResponse.class);
        return response.isOK();
    }
}
